home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Speccy ClassiX 1998
/
Speccy ClassiX 98.iso
/
amiga_system
/
the_aminet
/
dev
/
gcc
/
ixemulsrc.lha
/
ixemul-41.4
/
stack
/
stkext.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-05-23
|
3KB
|
134 lines
#include <stabs.h>
#include <bases.h>
asm("
.text
.even
.globl ___stkext_f
.globl ___stkext
.globl ___exit_stk
.globl ___stk_free
___stkext_f:
movel a0,sp@-
movel sp,a0 | memorize sp
moveml #0xc062,sp@- | preserves all registers
movel sp,a2 | memorize sp
addl #28:W,d1 | Used by this function itself
movel "A4(___stackborders)",a1| get upper border of stack in a1
movel a1@(4:W),a1
tstl "A4(___used_stack)"
bne l0
movel "A4(___SaveSP)",a1
l0: jbsr ___stkext | change to a stackframe with d0 bytes
movel "A4(___used_stack)",a6 | fix stored sp
addl d1,a6@(12:W)
movel a2,d0 | calculate number of bytes to copy
addl "A4(___stk_argbytes)",d0| to new stackframe in d0
addl d1,d0
cmpl a1,d0 | never copy over the bottom of the stack
jls l1
movel a1,d0
l1: subl a0,d0 | copy
subl d0,sp
movel sp,a1
movel "A4(_SysBase)",a6
jsr a6@(-0x270) | CopyMem(src:a0,dst:a1,siz:d0)
movel a2,a0
moveml a0@+,#0x4603
movel sp,a0 | Prepare cleanup
addl d1,a0
movel #___stkrst_f,a0@(8:W)
movel sp@+,a0
rts
___stkext:
movel a0,sp@-
moveml #0xf072,sp@- | preserves all registers
movel "A4(___stk_safezone)",d3
lea "A4(___stk_limit)",a2
lea "A4(___used_stack)",a3
addqw #4,a3
movel "A4(_SysBase)",a6
movel d0,d2
addl d3,d2
addl "A4(___stk_argbytes)",d2| required stack
l3: movel a3@,a0 | Look for a spare stackframe
movel a0,d0
jne l6
addl #20:W,d2 | no more stackframes - allocate a new one
movel "A4(___stk_minframe)",d1
cmpl d1,d2
jge l4
movel d1,d2
l4: movel d2,d0
moveql #1,d1 | MEMF_PUBLIC
jsr a6@(-0xc6) | AllocMem(siz:d0,typ:d1)
tstl d0
jeq ___stkovf | allocation failed
l5: movel d0,a0 | prepare new frame for use
addl d0,d2
movel d2,a0@(8:W)
addl #20:w,d0
movel d0,a0@(4:W)
jra l7
l6: movel a0@,a3@ | Remove spare stackframe from list
movel a0@(8:W),d0 | Test spare stackframe
subl a0@(4:W),d0
cmpl d0,d2
jls l7
addl #20:W,d0 | Not big enough
movel a0,a1
jsr a6@(-0xd2) | FreeMem(mem:a1,siz:d0)
jra l3
l7: movel a3@-,a0@ | Add it to the used list
movel a0,a3@
addqw #4,a0
movel a2@,a0@(12:W)
movel a0@,a2@ | Prepare ___top_of_stackframe variable
addl d3,a2@
lea a0@(4:W),a2
movel a2@+,a2@ | Prepare target sp
jsr a6@(-0x2dc) | StackSwap(sss:a0)
movel a2@,a0
addl #40:W,a2@ | Fix stored sp
moveml a0@+,#0x4e0f
movel a0@(4:W),sp@- | prepare returnaddress
movel a0@,a0
rts
___exit_stk:
tstl "A4(___used_stack)"
jeq ___stk_free
lea sp@(12:W),a0
movel "A4(___SaveSP)",d0 | Go back to first stackframe
jbsr ___stkrst
movel a0@,sp@- | restore argument of exit()
movel a0@-,sp@- | returnaddress for exit()
movel a0@-,sp@- | returnaddress for callfuncs()
movel a0@-,sp@- | our returnaddress
| jbsr ___stk_free
| rts
___stk_free:
movel a2,sp@-
movel a6,sp@- | Free all unused stackframes
movel "A4(_SysBase)",a6
lea "A4(___used_stack)",a2
addqw #4,a2
l8: movel a2@,a1 | Remove spare stackframe from list
movel a1,d0
jeq l9
movel a1@,a2@
movel a1@(8:W),d0 | Calculate size
subl a1@(4:W),d0
addl #20:W,d0
jsr a6@(-0xd2) | FreeMem(mem:a1,siz:d0)
jra l8
l9: movel sp@+,a6
movel sp@+,a2
rts
");
ADD2EXIT(__exit_stk,-50);